package com.huyi.common.config;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

/**
 * jedis加载
 * @ConditionalOnProperty 这个注解能够控制某个configuration是否生效。
 * 具体操作是通过其两个属性name以及havingValue来实现的，其中name用来从application.properties中读取某个属性值，如果该值为空，则返回false;
 * 如果值不为空，则将该值与havingValue指定的值进行比较，如果一样则返回true;否则返回false。
 * 如果返回值为false，则该configuration不生效；为true则生效。
 * 
 * @author shengli.hu
 *
 */
@Configuration
//@ConditionalOnProperty(name = "jedis.enabled", havingValue = "false")
@PropertySource("classpath:redis.properties")
public class JedisConfig {

	private Logger log = LoggerFactory.getLogger(JedisConfig.class);

	@Value("${redis.host}")
	private String host;

	@Value("${redis.port}")
	private int port;
	
	@Value("${redis.masterName}")
	private String masterName;

	@Value("${redis.sentinels}")
	private String sentinels;

	// 通用配置
	@Value("${redis.pool.password}")
	private String password;

	@Value("${redis.pool.config.maxTotal}")
	private int maxTotal;

	@Value("${redis.pool.config.maxIdle}")
	private int maxIdle;
	
	@Value("${redis.pool.config.minIdle}")
	private int minIdle;

	@Value("${redis.pool.config.maxWaitMillis}")
	private int maxWaitMillis;

	@Value("${redis.pool.config.database}")
	private int database;

	@Value("${redis.pool.config.timeout}")
	private int timeout;

	@Value("${redis.pool.config.testOnBorrow}")
	private boolean testOnBorrow;

	@Value("${redis.pool.config.testOnReturn}")
	private boolean testOnReturn;
	
	 /**
     * JedisPoolConfig 连接池
     *
     * @return
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最小连接数
        jedisPoolConfig.setMinIdle(minIdle);
        // 最大空闲数
        jedisPoolConfig.setMaxIdle(maxIdle);
        // 连接池的最大数据库连接数
        jedisPoolConfig.setMaxTotal(maxTotal);
        // 最大建立连接等待时间
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
        // 在空闲时检查有效性, 默认false
        jedisPoolConfig.setTestWhileIdle(testOnReturn);
        return jedisPoolConfig;
    }

	/**
	 * 单节点redis配置
	 * 
	 * @return JedisPool
	 */
/*	@Bean
	public JedisPool jedisPool(JedisPoolConfig config) {
		log.info("初始化redis配置start...");
		JedisPool pool = new JedisPool(config, host, port, timeout, password, database);
		log.info("redis启动成功...");
		return pool;
	}*/
	
	/**
	 * 主从哨兵模式redis配置
	 * 
	 * @return JedisPool
	 */
	@Bean
	public JedisSentinelPool jedisSentinelPool(JedisPoolConfig config) {
		log.info("初始化redis哨兵模式配置start...");
		// 哨兵列表
		String[] arrays = sentinels.split(",");
		Set<String> sentinelSets = new HashSet<String>(Arrays.asList(arrays));
		JedisSentinelPool pool = null;
		// 无密码
		if(StringUtils.isBlank(password)) {
			pool = new JedisSentinelPool(masterName, sentinelSets, config, timeout, null, database);
		} else {
			pool = new JedisSentinelPool(masterName, sentinelSets, config, timeout, password, database);
		}
		log.info("redis哨兵模式启动成功...");
		return pool;
	}
	
	/**
	 * redis集群配置
	 * 
	 * @return JedisPool
	 */
/*	@Bean
	public ShardedJedisPool shardedJedisPool(JedisPoolConfig config) {
		log.info("初始化redis集群配置start...");
		List<JedisShardInfo> poolList = new ArrayList<>();
		poolList.add(new JedisShardInfo(masterHost, masterPort));
		poolList.add(new JedisShardInfo(slave1Host, slave1Port));
		ShardedJedisPool pool = new ShardedJedisPool(config, poolList);
		log.info("redis集群启动成功...");
		return pool;
	}*/

}
